博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python-S9——Day84-ORM项目实战之权限、form以及modelform
阅读量:4602 次
发布时间:2019-06-09

本文共 22387 字,大约阅读时间需要 74 分钟。

  • 01 权限菜单显示

  • 02 Django路径的自动添加问题

  • 03 原生form实现增删改查

  • 04 modelform实现增删改查

01 权限菜单显示

1.1 优先查找项目中的templates,如果没有,然后再去查找应用中的templates下的模板文件;

 1.1.2 如果每个应用下都有相同名称的templates或者templatetags,会根据应用的创建顺序进行查找;

 1.1.3 为避免以上情况发生,建议在templates或者templatestags目录下分别建立应用名称,然后再放置.html模板文件或者my_tag.py文件;

整个项目的完整目录结构:

总结一下整个项目的开发流程:

  • 使用Pycharm创建项目,进行项目的命名
  • 使用Pycharm下的Tools》Run manage.py task启动shell窗口
  • startapp app01
  • startapp rbac(Role-Based Access Control,即基于角色的访问权限控制)详情见:
  • settings.py配置文件进行TEMPLATES以及INSTALLED_APPS的添加配置;
  • urls.py的配置;
  • app01/views.py的配置;
  • rbac/models.py的配置并进行数据库迁移操作 makemigrations\migrate
  • rbac/admin.py的注册配置,并引入class类;
  • 进行程序的解耦合操作,进行rbac/service/permissions.py以及rbac/service/rbac.py的配置;
  • 进行自定义templatetags的自定义,my_tags.py的配置;
  • 分别添加base.html menu.html users.html roles.html 等模板文件,进行extends、include、block等方法进行关联;
  • 将基础模板文件从根目录的templates目录迁移至rbac/templates目录下

settings.py

"""Django settings for s9day82_rbac project.Generated by 'django-admin startproject' using Django 1.11.1.For more information on this file, seehttps://docs.djangoproject.com/en/1.11/topics/settings/For the full list of settings and their values, seehttps://docs.djangoproject.com/en/1.11/ref/settings/"""import os# Build paths inside the project like this: os.path.join(BASE_DIR, ...)BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# Quick-start development settings - unsuitable for production# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEY = '0s(th#!ewf^xik5n&bqkqqjadz#q*vt+!hq(kzk5*-!t6@^0^i'# SECURITY WARNING: don't run with debug turned on in production!DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'app01.apps.App01Config',    'rbac.apps.RbacConfig',]MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    'rbac.service.rbac.ValidPermission',]from django.middleware.security import SecurityMiddlewareROOT_URLCONF = 's9day82_rbac.urls'TEMPLATES = [    {        'BACKEND': 'django.template.backends.django.DjangoTemplates',        'DIRS': [os.path.join(BASE_DIR, 'templates')]        ,        'APP_DIRS': True,        'OPTIONS': {            'context_processors': [                'django.template.context_processors.debug',                'django.template.context_processors.request',                'django.contrib.auth.context_processors.auth',                'django.contrib.messages.context_processors.messages',            ],        },    },]WSGI_APPLICATION = 's9day82_rbac.wsgi.application'# Database# https://docs.djangoproject.com/en/1.11/ref/settings/#databasesDATABASES = {    'default': {        'ENGINE': 'django.db.backends.sqlite3',        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),    }}# Password validation# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [    {        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',    },]# Internationalization# https://docs.djangoproject.com/en/1.11/topics/i18n/LANGUAGE_CODE = 'en-us'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)# https://docs.djangoproject.com/en/1.11/howto/static-files/STATIC_URL = '/static/'

urls.py

"""s9day82_rbac URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:    https://docs.djangoproject.com/en/1.11/topics/http/urls/Examples:Function views    1. Add an import:  from my_app import views    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')Class-based views    1. Add an import:  from other_app.views import Home    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')Including another URLconf    1. Import the include() function: from django.conf.urls import url, include    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))"""from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^users/$', views.users),    url(r'^users/add', views.add_user),    url(r'^users/delete/(\d+)', views.del_user),    url(r'^roles/', views.roles),    url(r'^login/', views.login),]

views.py

import refrom django.shortcuts import render, HttpResponse# Create your views here.from rbac.models import *from rbac.service.permissions import *class Per(object):    def __init__(self, actions):        self.actions = actions    def add(self):        return "add" in self.actions    def delete(self):        return "delete" in self.actions    def edit(self):        return "edit" in self.actions    def list(self):        return "list" in self.actionsdef users(request):    user_list = User.objects.all()    # permission_list = request.session.get("permission_list")    # print(permission_list)  # ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']    # 查询当前登录人的名字;    id = request.session.get("user_id")    user = User.objects.filter(id=id).first()    per = Per(request.actions)       return render(request, "users.html", locals())def add_user(request):    return HttpResponse("Add User......")def del_user(request, id):    return HttpResponse("Delete User..." + id)def roles(request):    role_list = Role.objects.all()    per = Per(request.actions)    return render(request, "roles.html", locals())def login(request):    if request.method == "POST":        user_obj = request.POST.get("user")        pwd = request.POST.get("pwd")        user = User.objects.filter(name=user_obj, pwd=pwd).first()        if user:            # #################在session中注册用户ID###########################;            request.session["user_id"] = user.pk            initial_session(user, request)            '''            此处的values()相当于:            temp = []#定义一个空列表;            for role in user.roles.all();#values属性,相当于循环该对象[
,
]> temp.append({ "title":role.title, "permissions__url":role.permissions.all() }) ''' return HttpResponse("登录成功!") return render(request, "login.html")

permissions.py

def initial_session(user, request):    # 方案1    # #################在session注册权限列表###########################;    # 查询当前登录用户的所有角色;    # ret = user.roles.all()    # print("ret", ret)  # 
,
]> # # # 查询当前用户的所有权限; # permissions = user.roles.all().values( # "permissions__url").distinct() # ret_role
# # # 进行数据的处理,生成列表; # permission_list = [] # for item in permissions: # permission_list.append(item["permissions__url"]) # print("permission_list", permission_list) # permission_list ['/users/', '/users/add'] # # request.session["permission_list"] = permission_list # 方案2; permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action").distinct() print("permissions ", permissions) #
permission_dict = {} for item in permissions: gid = item.get('permissions__group_id') if not gid in permission_dict: permission_dict[gid] = { "urls": [item["permissions__url"], ], "actions": [item["permissions__action"], ] } else: permission_dict[gid]["urls"].append(item["permissions__url"]) permission_dict[gid]["actions"].append(item["permissions__action"]) print(permission_dict) request.session["permission_dict"] = permission_dict # 注册菜单权限; permissions = user.roles.all().values("permissions__url", "permissions__action", "permissions__group__title").distinct() print("permissions", permissions) menu_permission_list = [] for item in permissions: if item["permissions__action"] == "list": menu_permission_list.append((item["permissions__url"], item["permissions__group__title"])) print(menu_permission_list) request.session["menu_permission_list"] = menu_permission_list

admin.py

from django.contrib import admin# Register your models here.from .models import *class PerConfig(admin.ModelAdmin):    list_display = ["title", "url", "group", "action"]admin.site.register(User)admin.site.register(Role)admin.site.register(Permission, PerConfig)admin.site.register(PermissionGroup)

rbac.py

from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponse, redirectimport re # 自定义中间件!class ValidPermission(MiddlewareMixin):    def process_request(self, request):        # 当前访问权限;        current_path = request.path_info        # 1、校验权限,是否是与白名单;        valid_url_list = ["/login/", "/reg/", "/admin/.*"]        for valid_url in valid_url_list:            ret = re.match(valid_url, current_path)            if ret:                return None        user_id = request.session.get("user_id")        if not user_id:            return redirect("/login/")        # # 2、判断是否登录        # permission_list = request.session.get(        #     "permission_list",        #     [])  # permission_list ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)']        #        # flag = False        # for permission in permission_list:        #     permission = "^%s$" % permission        #     ret = re.match(permission, current_path)        #     if ret:        #         flag = True        #         break        # if not flag:        #        # return None        #   3、校验是否登录;        permission_dict = request.session.get("permission_dict")        for item in permission_dict.values():            urls = item['urls']            for reg in urls:                reg = "^%s$" % reg                ret = re.match(reg, current_path)                if ret:                    print("actions", item['actions'])                    request.actions = item['actions']                    return None        return HttpResponse("没有访问权限!")

models.py

from django.db import models# Create your models here.class User(models.Model):    name = models.CharField(max_length=32)    pwd = models.CharField(max_length=32)    roles = models.ManyToManyField(to="Role")    def __str__(self):        return self.nameclass Role(models.Model):    title = models.CharField(max_length=32)    permissions = models.ManyToManyField(to="Permission")    def __str__(self):        return self.titleclass Permission(models.Model):    title = models.CharField(max_length=32)    url = models.CharField(max_length=32)    action = models.CharField(max_length=32, default="")    group = models.ForeignKey("PermissionGroup", default=1)    def __str__(self):        return self.titleclass PermissionGroup(models.Model):    title = models.CharField(max_length=32)    def __str__(self):        return self.title

base.html

    
Title

{

{ user.name }}

{% load my_tags %}
{% block con %} {% endblock %}

menu.html

{% for item in menu_permission_list %}
{ item.1 }}

{% endfor %}

users.html

{% extends 'base.html' %}{% block con %}    

用户列表

{% if per.add %} 添加用户 {% endif %}
{% for user in user_list %}
{% endfor %}
序号 姓名 角色 操作
{
{ forloop.counter }}
{
{ user.name }}
{% for role in user.roles.all %} {
{ role.title }} {% endfor %}
{% if per.delete %} 删除 {% endif %} {% if per.edit %} 编辑 {% endif %}
{% endblock %}

login.html

    
Title

登录页面

{% csrf_token %} 用户名:
密码:

my_tags.py

from django import templateregister = template.Library()@register.inclusion_tag("menu.html")def get_menu(request, ):    # 获取当前用户可以放到菜单栏中的权限;    menu_permission_list = request.session["menu_permission_list"]    return {
"menu_permission_list": menu_permission_list}

02 Django路径的自动添加问题

2.1 settings.py文件中,APPEND_SLASH默认值为True;

2.2 在setings.py中,将APPEND_SLASH调整为False;

#设置项是否开启URL访问地址后面不为/跳转至带有/的路径;

03 原生form实现增删改查

3.1 创建Django项目并制定Python解释器下安装的Django==“1.11.1” version;

3.2 基于form实现的图书管理系统的增删改查步骤;

  • 创建django项目并指定app及Python内置解释器;
  • 检查settings.py是否配置了TEMPLATES以及INSTALLED_APPS;
  • 配置urls.py;
  • 编写视图函数views.py;
  • 编写ORM——models.py;
  • 进行admin.py的注册;
  • 通过Pycharm下的Run manage.py task进行数据库的迁移以及createsuperuser操作;
  • 编写模板——add.html\books.html\edit.html;

urls.py;

"""FormsDemo URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:    https://docs.djangoproject.com/en/1.11/topics/http/urls/Examples:Function views    1. Add an import:  from my_app import views    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')Class-based views    1. Add an import:  from other_app.views import Home    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')Including another URLconf    1. Import the include() function: from django.conf.urls import url, include    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))"""from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^books/', views.books),    url(r'^book/add', views.add_book),    url(r'^book/edit/(\d+)', views.edit_book),]

views.py;

from django.shortcuts import render, redirect# Create your views here.from .models import *def books(request):    book_list = Book.objects.all()    return render(request, "books.html", locals())def add_book(request):    if request.method == "POST":        title = request.POST.get("title")        price = request.POST.get("price")        date = request.POST.get("date")        publish_id = request.POST.get("publish_id")        author_pk_list = request.POST.getlist("author_pk_list")        book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish_id)        book_obj.authors.add(*author_pk_list)        return redirect('/books/')    publish_list = Publish.objects.all()    author_list = Author.objects.all()    return render(request, "add.html", locals())def edit_book(request, edit_book_id):    if request.method == "POST":        title = request.POST.get("title")        price = request.POST.get("price")        date = request.POST.get("date")        publish_id = request.POST.get("publish_id")        author_pk_list = request.POST.getlist("author_pk_list")        Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish_id=publish_id)        book_obj = Book.objects.filter(pk=edit_book_id).first()        book_obj.authors.set(author_pk_list)        return redirect('/books/')    edit_book = Book.objects.filter(pk=edit_book_id).first()    publish_list = Publish.objects.all()    author_list = Author.objects.all()    return render(request, "edit.html", locals())

models.py;

from django.db import models# Create your models here.class Book(models.Model):    title = models.CharField(max_length=32)    price = models.DecimalField(max_digits=8, decimal_places=2)  # 999999.99    date = models.DateField()    publish = models.ForeignKey("Publish")    authors = models.ManyToManyField("Author")    def __str__(self):        return self.titleclass Publish(models.Model):    name = models.CharField(max_length=32)    def __str__(self):        return self.nameclass Author(models.Model):    name = models.CharField(max_length=32)    def __str__(self):        return self.name

admin.py;

from django.contrib import admin# Register your models here.from .models import *admin.site.register(Book)admin.site.register(Author)admin.site.register(Publish)

books.html

 

    
Books
    {
    % for book in book_list %}
    {
    % endfor %}
    {
    { book.title }}
    {
    { book.price }}
    {
    { book.date|date:"Y-m-d" }}
    {
    { book.publish.name }}
    {
    { book.authors.all }}

add.html

    
add

添加页面

{
% csrf_token %}

书籍名称

价格

日期

出版社

作者

 edit.html

    
add

编辑页面

{
% csrf_token %}

书籍名称

价格

日期

出版社

作者

04 modelform实现增删改查

4.1 使用forms组件代替form表单;

class BookForm(forms.Form):    title = forms.CharField(max_length=32, label="书籍名称")    price = forms.DecimalField(max_digits=8, decimal_places=2, label="价格")  # 999999.99    date = forms.DateField(label="日期",                           widget=widgets.TextInput(attrs={
"type": "date"}) ) # gender = forms.ChoiceField(choices=((1, "男"), (2, "女"), (3, "其他"),)) # publish = forms.ChoiceField(choices=Publish.objects.all().values_list("pk", "name")) publish = forms.ModelChoiceField(queryset=Publish.objects.all()) authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())

4.2 基于ModelForm进行精简开发;

views.py

from django.shortcuts import render, redirect# Create your views here.from .models import *from django import formsfrom django.forms import widgetsfrom django.forms import ModelFormfrom django.forms import widgets as wid'''class BookForm(forms.Form):    title = forms.CharField(max_length=32, label="书籍名称")    price = forms.DecimalField(max_digits=8, decimal_places=2, label="价格")  # 999999.99    date = forms.DateField(label="日期",                           widget=widgets.TextInput(attrs={"type": "date"})                           )    # gender = forms.ChoiceField(choices=((1, "男"), (2, "女"), (3, "其他"),))    # publish = forms.ChoiceField(choices=Publish.objects.all().values_list("pk", "name"))    publish = forms.ModelChoiceField(queryset=Publish.objects.all())    authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())'''class BookForm(ModelForm):    class Meta:        model = Book        fields = "__all__"        # fields = ["title", "price"]        labels = {            "title": "书籍名称",            "price": "价格",            "date": "书籍日期",            "publish": "出版社",            "authors": "作者",        }        widgets = {            "title": wid.TextInput(attrs={
"class": "form-control"}), "price": wid.TextInput(attrs={
"class": "form-control"}), "date": wid.TextInput(attrs={
"class": "form-control"}), "publish": wid.TextInput(attrs={
"class": "form-control"}), "authors": wid.TextInput(attrs={
"class": "form-control"}), }def books(request): book_list = Book.objects.all() return render(request, "books.html", locals())def add_book(request): if request.method == "POST": form = BookForm(request.POST) if form.is_valid(): form.save() return redirect("/books/") form = BookForm() return render(request, "add.html", locals())def edit_book(request, edit_book_id): edit_book = Book.objects.filter(pk=edit_book_id).first() if request.method == "POST": form = BookForm(request.POST, instance=edit_book) form.save() return redirect("/books/") form = BookForm(instance=edit_book) return render(request, "edit.html", locals())

add.html

    
add

添加页面

{% include 'form.html' %}

books.html

    
Books
    {% for book in book_list %}
    {% endfor %}
    {
    { book.title }}
    {
    { book.price }}
    {
    { book.date|date:"Y-m-d" }}
    {
    { book.publish.name }}
    {
    { book.authors.all }}

edit.html

    
add

编辑页面

{% include 'form.html' %}

form.html

{% csrf_token %} {% for field in form %}
{
{ field.label }} {
{ field }}
{% endfor %}

 

转载于:https://www.cnblogs.com/tqtl911/p/9596198.html

你可能感兴趣的文章
有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?
查看>>
005-四种常见的 POST 提交数据方式
查看>>
nginx应用总结(2)--突破高并发的性能优化
查看>>
linux安装配置SVN并设置钩子
查看>>
Flyweight享元模式(结构型模式)
查看>>
Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势
查看>>
Linux DNS 查询剖析(第四部分) | Linux 中国
查看>>
(转)azkaban job参数说明
查看>>
JS 用 prototype 扩展实现string过滤空格
查看>>
如何在Salesforce中进行代码开发
查看>>
数字信号处理实验(一)——DTFT
查看>>
算法:【一列数的规则如下: 1、1、2、3、5、8、13、21、34 ,求第30位数是多少, 用递归算法实现。(C#语言)】...
查看>>
2016年第51周日三岁看大?
查看>>
[转][android深入学习]android窗口管理机制
查看>>
从零开始创建一个Android主屏幕Widget http://www.it168.com
查看>>
[Step By Step]SAP HANA PAL多元指数回归预测分析Multiple Exponential Regression编程实例EXPREGRESSION(模型)...
查看>>
Deep Learning(深度学习)学习笔记整理系列之(三)
查看>>
express中connect-flash中间件的使用
查看>>
[Django] 查看orm自己主动运行的原始查询sql
查看>>
机器学习 Top 20 Python 开源项目
查看>>